package com.happy.mycar;

import static android.bluetooth.BluetoothGattCharacteristic.FORMAT_UINT8;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

class RssiAnalyzer {
    // 可配置参数
    private final int windowSize;       // 滑动窗口大小（建议10-20）
    private int posThreshold;   // 靠近阈值（建议3dB）
    private int negThreshold;   // 远离阈值（建议-3dB）
    private final int confirmCount;      // 状态切换确认次数（建议3次）

    // 运行时状态
    private final Queue<Integer> window = new ArrayDeque<>();
    private State currentState = State.UNKNOWN;
    private int confirmCounter;

    public enum State {
        UNKNOWN,      // 初始状态
        APPROACHING,  // 正在靠近
        MOVING_AWAY   // 正在远离
    }

    public RssiAnalyzer(int windowSize, int posThreshold, int negThreshold, int confirmCount) {
        this.windowSize = windowSize;
        this.posThreshold = posThreshold;
        this.negThreshold = negThreshold;
        this.confirmCount = confirmCount;
    }

    private int windowSum = 0; // 窗口内的RSSI值之和

    /**
     * 添加新的RSSI值并触发分析
     */
    public void addRssi(int rssi) {
        // 窗口填满后开始分析
        if (window.size() == windowSize) {
            int oldestRssi = window.poll();
            windowSum -= oldestRssi;
            window.add(rssi);
            windowSum += rssi;
            analyze();
        } else {
            window.add(rssi);
            windowSum += rssi;
        }
    }

    /**
     * 获取当前状态
     */
    public State getCurrentState() {
        return currentState;
    }

    /**
     * 核心分析逻辑
     */
    private void analyze() {
        // 1. 计算移动平均
        final int currentAvg = calculateAverage();
        //final int pastAvg = calculateHalfAverage();
        //计算窗口前三项
        //final int pastAvg = window.peek();
        // 3. 计算变化量
        //final int delta = currentAvg - pastAvg;

        // 4. 状态机判断
        if (currentAvg > posThreshold) {
            handlePositiveDelta();
        } else if (currentAvg < negThreshold) {
            handleNegativeDelta();
        } else {
            confirmCounter = Math.max(0, confirmCounter - 1);
        }
    }

    /**
     * 处理正变化量（靠近）
     */
    private void handlePositiveDelta() {
        if (currentState != State.APPROACHING) {
            if (++confirmCounter >= confirmCount) {
                currentState = State.APPROACHING; // 切换到靠近状态
                confirmCounter = 0; // 重置计数器
            }
        } else {
            confirmCounter = 0; // 已处于靠近状态时重置计数器
        }
    }

    /**
     * 处理负变化量（远离）
     */
    private void handleNegativeDelta() {
        if (currentState != State.MOVING_AWAY) {
            if (++confirmCounter >= confirmCount) {
                currentState = State.MOVING_AWAY; // 切换到远离状态
                confirmCounter = 0; // 重置计数器
            }
        } else {
            confirmCounter = 0; // 已处于远离状态时重置计数器
        }
    }

    /**
     * 计算队列平均值
     */
    private int calculateAverage() {
        return windowSum / windowSize;
    }

    public void setThreshold(int posThreshold, int negThreshold) {
        this.posThreshold = posThreshold;
        this.negThreshold = negThreshold;
    }
}

public class CBLEDevice extends BluetoothGattCallback {
    ESP_Config esp_config = new ESP_Config();

    public ESP_Config getEspConfig() {
        return esp_config;
    }

    RssiAnalyzer analyzer = new RssiAnalyzer(10, esp_config.ESP32_RSSI_POS_THRESHOLD, esp_config.ESP32_RSSI_NEG_THRESHOLD, 3);

    private BroadcastReceiver bluetoothStateReceiver;

    public void registerReceiver() {
        bluetoothStateReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
                    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                    if (state == BluetoothAdapter.STATE_OFF) {
                        // 蓝牙已关闭
                        handleBluetoothDisabled();
                    } else if (state == BluetoothAdapter.STATE_ON) {
                        // 蓝牙已打开
                        handleBluetoothEnabled();
                    }
                }
            }
        };

        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        context.registerReceiver(bluetoothStateReceiver, filter);
    }

    public void unregisterReceiver() {
        if (bluetoothStateReceiver != null) {
            context.unregisterReceiver(bluetoothStateReceiver);
            bluetoothStateReceiver = null;
        }
    }

    private void handleBluetoothDisabled() {
        isScaning.set(false);
        System.out.println("蓝牙已关闭，请打开蓝牙以继续使用");
    }

    private void handleBluetoothEnabled() {
        // 处理蓝牙打开事件，例如重新初始化蓝牙功能
        System.out.println("蓝牙已打开，可以继续使用");
    }

    private static CBLEDevice instance; // 单例实例
    private AtomicBoolean isConnected = new AtomicBoolean(false), isScaning = new AtomicBoolean(false); // 是否连接
    private Context context;  // 上下文对象

    public void setThreshold(int posThreshold, int negThreshold) {
        esp_config.ESP32_RSSI_POS_THRESHOLD = posThreshold;
        esp_config.ESP32_RSSI_NEG_THRESHOLD = negThreshold;
        analyzer.setThreshold(posThreshold, negThreshold);
    }

    private Context contextActivity;
    private TextView logTextView; // 用于显示日志的 TextView
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    public void setContext(Context context, TextView logTextView) {
        contextActivity = context;
        this.context = context;
        this.logTextView = logTextView;
    }

    public void LoadConfig(SharedPreferences sharedPreferences) {
        esp_config.LoadConfig(sharedPreferences);
        setThreshold(esp_config.ESP32_RSSI_POS_THRESHOLD, esp_config.ESP32_RSSI_NEG_THRESHOLD);
    }

    public static CBLEDevice getInstance() {
        if (instance == null) {
            instance = new CBLEDevice();
            //ReleaseBle.closeAndroidPDialog();
        }
        return instance;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public void setLogTextView(TextView logTextView) {
        this.logTextView = logTextView;
    }

    private BluetoothGatt bluetoothGatt;  // GATT 连接对象

    public BluetoothDevice getBluetoothDevice() {
        return bluetoothGatt.getDevice();
    }


    ScanCallback mSscanCallback = null;

    /**
     * 尝试连接指定名称的未配对蓝牙设备
     *
     * @param deviceName 蓝牙设备名称
     */
    public synchronized void connectToBLEDevice(String deviceName) {
        if (bluetoothAdapter == null) {
            appendLog("设备不支持蓝牙");
            return;
        }
        if (context == null) {
            appendLog("Context 未设置，无法正常操作设备");
            return;
        }
        if (isScaning.get()) {
            appendLog("正在扫描设备");
            return;
        }
        //首先检查有没有配对叫“MyCar”的设备
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        //检查蓝牙是否打开
        if (!bluetoothAdapter.isEnabled()) {
            appendLog("尝试打开蓝牙以继续使用");
            bluetoothAdapter.enable();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //release();
        //处理扫描过程中蓝牙可能被关闭的情况
        BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
        if (bluetoothLeScanner != null) {
            isScaning.set(true);
            appendLog("正在扫描设备");
            mSscanCallback = getScanCallback(deviceName, bluetoothLeScanner);
            List<ScanFilter> filters = new ArrayList<>();
            ScanFilter filter = new ScanFilter.Builder()
                    .setDeviceName("MyCar")
                    .build();
            filters.add(filter);
            ScanSettings scanSettings = new ScanSettings.Builder()
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
                    .build();
            bluetoothLeScanner.startScan(filters, scanSettings, mSscanCallback);
        }
    }

    @NonNull
    private ScanCallback getScanCallback(String deviceName, BluetoothLeScanner bluetoothLeScanner) {
        BluetoothLeScanner finalBluetoothLeScanner = bluetoothLeScanner;
        ScanCallback scanCallback = new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);
                if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                BluetoothDevice device = result.getDevice();
                if (device != null && deviceName.equals(device.getName())) {
                    isConnected.set(true);
                    if (bluetoothGatt != null) {
                        bluetoothGatt.close();
                        bluetoothGatt = null;
                    }
                    bluetoothGatt = device.connectGatt(context, false, CBLEDevice.this, BluetoothDevice.TRANSPORT_LE);
                    System.out.println("正在尝试连接设备：" + deviceName);
                }
                finalBluetoothLeScanner.stopScan(this);
            }

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
                if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                finalBluetoothLeScanner.stopScan(this);
                appendLog("BLE 扫描失败，错误码：" + errorCode);
                isScaning.set(false);
            }
        };
        return scanCallback;
    }

    private void appendLog(String message) {
        // After
        if (contextActivity instanceof Activity) {
            ((Activity) contextActivity).runOnUiThread(() -> {
                if (logTextView != null)
                    logTextView.setText(message);
            });
        }
    }
//向BLE服务发送消息

    /**
     * 断开蓝牙连接
     */
    public void disconnect() {
        if (bluetoothGatt != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            bluetoothGatt.disconnect();
        }
    }

    /**
     * 动态更新 RSSI
     */
    private Thread rssiUpdateThread; // 定义线程为类的成员变量

    public synchronized void updateRSSI() {
        if (bluetoothGatt != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            rssiUpdateThread = new Thread(() -> {
                while (isConnected.get() && !Thread.currentThread().isInterrupted()) {
                    try {
                        if (bluetoothGatt != null)
                            bluetoothGatt.readRemoteRssi();
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt(); // 恢复中断状态
                    }
                }
            });
            rssiUpdateThread.start();
        }
    }

    // 提供停止线程的方法
    public synchronized void stopRSSIUpdate() {
        if (rssiUpdateThread != null && rssiUpdateThread.isAlive()) {
            rssiUpdateThread.interrupt();
            rssiUpdateThread = null;
        }
    }

    synchronized void release() {
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        characteristic = null;
        if (bluetoothGatt != null) {
            bluetoothGatt.close();
            //延时一秒，确保关闭完成
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            bluetoothGatt = null;
        }
    }

    // 重写 BluetoothGattCallback 的方法
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        switch (newState) {
            case BluetoothProfile.STATE_CONNECTING:
                appendLog("正在连接...");
                break;
            case BluetoothProfile.STATE_CONNECTED:
                updateNotification("遥控器已连接");
                appendLog("开始查找服务");
                gatt.discoverServices(); // 开始服务发现
                break;
            case BluetoothProfile.STATE_DISCONNECTING:
                appendLog("正在断开...");
                stopRSSIUpdate();
                break;
            case BluetoothProfile.STATE_DISCONNECTED:
                updateNotification("遥控器已断开");
                appendLog("连接断开");
                isConnected.set(false);
                isScaning.set(false);
                esp_config.IS_LOCK = true;
                break;
        }
    }

    private static final UUID CUSTOM_SERVICE_UUID = UUID.fromString("91486214-AB7F-E39C-5A68-C1F2D4A9B73E");
    private static final UUID CUSTOM_CHARACTERISTIC_UUID = UUID.fromString("3EB7A9D4-F2C1-685A-9CE3-7FAB14624891");
    BluetoothGattCharacteristic characteristic;

    public void updateNotification(String content) {
        Intent intent = new Intent(context, MainActivity.class);
        // 如果希望在应用已在后台运行时，将其带到前台并清除之前的活动栈，可以添加以下标志
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "channel_id")
                .setContentTitle("智能车钥匙")
                .setContentText(content)
                .setOngoing(true)
                .setSmallIcon(R.drawable.ic_launcher_foreground).setContentIntent(pendingIntent)
                .setPriority(NotificationCompat.PRIORITY_HIGH);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.notify(1, builder.build());
        }
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        //打印所有服务UUID
        for (BluetoothGattService service : gatt.getServices()) {
            System.out.println("Service UUID: " + service.getUuid());
            for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                System.out.println("Characteristic UUID: " + characteristic.getUuid());
            }
        }
        if (status == BluetoothGatt.GATT_SUCCESS) {
            appendLog("正在查找服务");
            BluetoothGattService service = gatt.getService(CUSTOM_SERVICE_UUID);
            if (service != null) {
                characteristic = service.getCharacteristic(CUSTOM_CHARACTERISTIC_UUID);
                if (characteristic != null) {
                    appendLog("找到合法服务");
                    esp_config.IS_LOCK = true;
                    updateRSSI();
                } else {
                    disconnect();
                    appendLog("未找到合法服务");
                }
            }
        } else {
            disconnect();
            appendLog("查找服务失败: " + status);
        }
    }

    public synchronized boolean isConnected() {
        return isConnected.get();
    }

    @Override
    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
        super.onReadRemoteRssi(gatt, rssi, status);

        if (status == BluetoothGatt.GATT_SUCCESS) {
            analyzer.addRssi(rssi);
            switch (analyzer.getCurrentState()) {
                case APPROACHING:
                    appendLog("靠近车辆，RSSI: " + rssi);
                    if (esp_config.AUTO_UNLOCK && esp_config.IS_LOCK) {
                        unlockCar();
                    }
                    break;
                case MOVING_AWAY:
                    appendLog("远离车辆，RSSI: " + rssi);
                    if (!esp_config.IS_LOCK && esp_config.AUTO_LOCK) {
                        lockCar();
                    }
                    break;
                case UNKNOWN:
                    appendLog("未知状态，RSSI: " + rssi);
                    break;
            }
        }
    }

    @Override
    public void onCharacteristicWrite(
            BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            appendLog("操作成功");
        } else {
            esp_config.IS_LOCK = !esp_config.IS_LOCK;
            appendLog("操作失败: " + status);
        }
    }

    public synchronized void unlockCar() {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            esp_config.IS_LOCK = false;
            characteristic.setValue(esp_config.UNLOCK_KEY, FORMAT_UINT8, 0); // 示例值
            bluetoothGatt.writeCharacteristic(characteristic);
        }
    }

    public synchronized void lockCar() {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            esp_config.IS_LOCK = true;
            characteristic.setValue(esp_config.LOCK_KEY, FORMAT_UINT8, 0); // 示例值
            bluetoothGatt.writeCharacteristic(characteristic);
        }
    }

    public synchronized void trunkCar() {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            esp_config.IS_LOCK = true;
            characteristic.setValue(esp_config.TRUNK_KEY, FORMAT_UINT8, 0); // 示例值
            bluetoothGatt.writeCharacteristic(characteristic);
        }
    }

    private void SendCommandToBle(byte cmd,int delay)
    {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }

            byte[] command = new byte[1 + 4];
            command[0] = cmd; // 命令字

            // 将 delay 转换为字节数组
            command[1] = (byte) (delay & 0xff);
            command[2] = (byte) ((delay >> 8) & 0xff);
            command[3] = (byte) ((delay >> 16) & 0xff);
            command[4] = (byte) ((delay >> 24) & 0xff);
            characteristic.setValue(command);
            bluetoothGatt.writeCharacteristic(characteristic);
        }
    }

    public synchronized void openWindow() {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            SendCommandToBle((byte) esp_config.WINDOW_KEY,300); // 300毫秒延时
        }
    }

    public synchronized void closeWindow() {
        if (characteristic != null) {
            if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            esp_config.IS_LOCK = true;
            characteristic.setValue(esp_config.WINDOW_KEY, FORMAT_UINT8, 0); // 示例值
            bluetoothGatt.writeCharacteristic(characteristic);
        }
    }
}